package com.sinnatec.collection;

import org.apache.commons.collections4.*;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;

public class CollectionUtil{

    private CollectionUtil(){

    }
    public static <T> Collection<T> emptyCollection() {
        return CollectionUtils.emptyCollection();
    }

    public static <T> Collection<T> emptyIfNull(final Collection<T> collection) {
        return CollectionUtils.emptyIfNull(collection);
    }

    public static <O> Collection<O> union(final Iterable<? extends O> a, final Iterable<? extends O> b) {
        return CollectionUtils.union(a,b);
    }

    public static <O> Collection<O> intersection(final Iterable<? extends O> a, final Iterable<? extends O> b) {
        return CollectionUtils.intersection(a,b);
    }

    public static <O> Collection<O> disjunction(final Iterable<? extends O> a, final Iterable<? extends O> b) {
        return CollectionUtils.disjunction(a,b);
    }

    public static <O> Collection<O> subtract(final Iterable<? extends O> a, final Iterable<? extends O> b) {
        return CollectionUtils.subtract(a,b);
    }

    public static <O> Collection<O> subtract(final Iterable<? extends O> a,
                                             final Iterable<? extends O> b,
                                             final Predicate<O> p) {
        return CollectionUtils.subtract(a,b,p);
    }

    public static boolean containsAll(final Collection<?> coll1, final Collection<?> coll2) {
        return CollectionUtils.containsAll(coll1,coll2);
    }

    public static <T> boolean containsAny(final Collection<?> coll1, @SuppressWarnings("unchecked") final T... coll2) {
        return CollectionUtils.containsAny(coll1,coll2);
    }

    public static boolean containsAny(final Collection<?> coll1, final Collection<?> coll2) {
        return CollectionUtils.containsAny(coll1,coll2);
    }

    public static <O> Map<O, Integer> getCardinalityMap(final Iterable<? extends O> coll) {
        return CollectionUtils.getCardinalityMap(coll);
    }

    public static boolean isSubCollection(final Collection<?> a, final Collection<?> b) {
        return CollectionUtils.isSubCollection(a,b);
    }

    public static boolean isProperSubCollection(final Collection<?> a, final Collection<?> b) {
        return CollectionUtils.isProperSubCollection(a,b);
    }

    public static boolean isEqualCollection(final Collection<?> a, final Collection<?> b) {
        return CollectionUtils.isEqualCollection(a,b);
    }

    public static <E> boolean isEqualCollection(final Collection<? extends E> a,
                                                final Collection<? extends E> b,
                                                final Equator<? super E> equator) {
        return CollectionUtils.isEqualCollection(a,b,equator);
    }

    public static <T> boolean filter(final Iterable<T> collection, final Predicate<? super T> predicate) {
        return CollectionUtils.filter(collection,predicate);
    }

    public static <T> boolean filterInverse(final Iterable<T> collection, final Predicate<? super T> predicate) {
        return CollectionUtils.filterInverse(collection,predicate);
    }
    public static <C> void transform(final Collection<C> collection,
                                     final Transformer<? super C, ? extends C> transformer) {
        CollectionUtils.transform(collection,transformer);
    }

    public static <O> Collection<O> select(final Iterable<? extends O> inputCollection,
                                           final Predicate<? super O> predicate) {
        return CollectionUtils.select(inputCollection,predicate);
    }

    public static <O, R extends Collection<? super O>> R select(final Iterable<? extends O> inputCollection,
                                                                final Predicate<? super O> predicate, final R outputCollection) {
        return CollectionUtils.select(inputCollection,predicate,outputCollection);
    }

    public static <O, R extends Collection<? super O>> R select(final Iterable<? extends O> inputCollection,
                                                                final Predicate<? super O> predicate, final R outputCollection, final R rejectedCollection) {

        return CollectionUtils.select(inputCollection,predicate,outputCollection,rejectedCollection);
    }

    public static <O> Collection<O> selectRejected(final Iterable<? extends O> inputCollection,
                                                   final Predicate<? super O> predicate) {
        return CollectionUtils.selectRejected(inputCollection,predicate);
    }

    public static <O, R extends Collection<? super O>> R selectRejected(final Iterable<? extends O> inputCollection,
                                                                        final Predicate<? super O> predicate, final R outputCollection) {
        return CollectionUtils.selectRejected(inputCollection,predicate,outputCollection);
    }

    public static <I, O> Collection<O> collect(final Iterable<I> inputCollection,
                                               final Transformer<? super I, ? extends O> transformer) {
        return CollectionUtils.collect(inputCollection,transformer);
    }

    public static <I, O> Collection<O> collect(final Iterator<I> inputIterator,
                                               final Transformer<? super I, ? extends O> transformer) {
        return CollectionUtils.collect(inputIterator,transformer);
    }

    public static <I, O, R extends Collection<? super O>> R collect(final Iterable<? extends I> inputCollection,
                                                                    final Transformer<? super I, ? extends O> transformer, final R outputCollection) {
        return CollectionUtils.collect(inputCollection,transformer,outputCollection);
    }

    public static <I, O, R extends Collection<? super O>> R collect(final Iterator<? extends I> inputIterator,
                                                                    final Transformer<? super I, ? extends O> transformer, final R outputCollection) {
        return CollectionUtils.collect(inputIterator,transformer,outputCollection);
    }

    public static <T> boolean addIgnoreNull(final Collection<T> collection, final T object) {
        return CollectionUtils.addIgnoreNull(collection,object);
    }

    public static <C> boolean addAll(final Collection<C> collection, final Iterable<? extends C> iterable) {
        return CollectionUtils.addAll(collection,iterable);
    }

    public static <C> boolean addAll(final Collection<C> collection, final Iterator<? extends C> iterator) {
        return CollectionUtils.addAll(collection,iterator);
    }

    public static <C> boolean addAll(final Collection<C> collection, final Enumeration<? extends C> enumeration) {
        return CollectionUtils.addAll(collection,enumeration);
    }

    public static <C> boolean addAll(final Collection<C> collection, final C... elements) {
        return CollectionUtils.addAll(collection,elements);
    }

    public static Object get(final Object object, final int index) {
        return CollectionUtils.get(object,index);
    }

    public static <K,V> Map.Entry<K, V> get(final Map<K,V> map, final int index) {
        return CollectionUtils.get(map,index);
    }

    public static int size(final Object object) {
        return CollectionUtils.size(object);
    }

    public static boolean sizeIsEmpty(final Object object) {
        return CollectionUtils.sizeIsEmpty(object);
    }

    public static boolean isEmpty(final Collection<?> coll) {
        return CollectionUtils.isEmpty(coll);
    }

    public static boolean isNotEmpty(final Collection<?> coll) {
        return CollectionUtils.isNotEmpty(coll);
    }

    public static void reverseArray(final Object[] array) {
        CollectionUtils.reverseArray(array);
    }

    public static boolean isFull(final Collection<? extends Object> coll) {
        return CollectionUtils.isFull(coll);
    }

    public static int maxSize(final Collection<? extends Object> coll) {
        return CollectionUtils.maxSize(coll);
    }

    public static <O extends Comparable<? super O>> List<O> collate(final Iterable<? extends O> a,
                                                                    final Iterable<? extends O> b) {
        return CollectionUtils.collate(a,b);
    }

    public static <O extends Comparable<? super O>> List<O> collate(final Iterable<? extends O> a,
                                                                    final Iterable<? extends O> b,
                                                                    final boolean includeDuplicates) {
        return CollectionUtils.collate(a,b,includeDuplicates);
    }

    public static <O> List<O> collate(final Iterable<? extends O> a, final Iterable<? extends O> b,
                                      final Comparator<? super O> c) {
        return collate(a, b, c, true);
    }

    public static <O> List<O> collate(final Iterable<? extends O> a, final Iterable<? extends O> b,
                                      final Comparator<? super O> c, final boolean includeDuplicates) {

        return CollectionUtils.collate(a,b,c,includeDuplicates);
    }

    public static <E> Collection<List<E>> permutations(final Collection<E> collection) {
        return CollectionUtils.permutations(collection);
    }

    public static <C> Collection<C> retainAll(final Collection<C> collection, final Collection<?> retain) {
        return CollectionUtils.retainAll(collection, retain);
    }

    public static <E> Collection<E> retainAll(final Iterable<E> collection,
                                              final Iterable<? extends E> retain,
                                              final Equator<? super E> equator) {

        return CollectionUtils.retainAll(collection,retain,equator);
    }

    public static <E> Collection<E> removeAll(final Collection<E> collection, final Collection<?> remove) {
        return CollectionUtils.removeAll(collection, remove);
    }

    public static <E> Collection<E> removeAll(final Iterable<E> collection,
                                              final Iterable<? extends E> remove,
                                              final Equator<? super E> equator) {

        return CollectionUtils.removeAll(collection,remove,equator);
    }

    public static <C> Collection<C> predicatedCollection(final Collection<C> collection,
                                                         final Predicate<? super C> predicate) {
        return CollectionUtils.predicatedCollection(collection, predicate);
    }

    public static <E> Collection<E> transformingCollection(final Collection<E> collection,
                                                           final Transformer<? super E, ? extends E> transformer) {
        return CollectionUtils.transformingCollection(collection, transformer);
    }

    public static <E> E extractSingleton(final Collection<E> collection) {
        return CollectionUtils.extractSingleton(collection);
    }

    public static <E> ArrayList<E> newArrayList() {
        return new ArrayList<>();
    }

    public static <E> LinkedList<E> newLinkedList() {
        return new LinkedList<>();
    }

    public static <E> CopyOnWriteArrayList<E> newCopyOnWriteArrayList() {
        return new CopyOnWriteArrayList<>();
    }

}
